package com.ah.ues.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;

public class AesUtil {
    private static final Logger log = LoggerFactory.getLogger(AesUtil.class);

    private static final String gcm256algorithm = "AES/GCM/NoPadding";
    public static final String AES = "AES";

    public static byte[] createSecKey() throws NoSuchAlgorithmException {
        KeyGenerator generator = KeyGenerator.getInstance(AES);
        generator.init(256);
        SecretKey secretKey = generator.generateKey();
        return secretKey.getEncoded();
    }

    public static byte[] decrypt(byte[] content, byte[] keyBytes) {
        try {
            if (content == null) {
                return null;
            }
            Cipher cipher = Cipher.getInstance(gcm256algorithm);
            SecretKey key = new SecretKeySpec(keyBytes, "AES");

            cipher.init(Cipher.ENCRYPT_MODE, key);
            if (content.length < 12 + 16) throw new IllegalArgumentException();
            GCMParameterSpec params = new GCMParameterSpec(128, content, 0, 12);
            cipher.init(Cipher.DECRYPT_MODE, key, params);
            return cipher.doFinal(content, 12, content.length - 12);
        } catch (Exception e) {
            log.error("AESGCM256解密文本处理失败,error:", e);
            throw new RuntimeException(e);
        }
    }

    public static byte[] encrypt(byte[] content, byte[] keyBytes) {
        try {
            if (content == null) {
                return null;
            }
            SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance(gcm256algorithm);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] iv = cipher.getIV();
            assert iv.length == 12;
            byte[] encryptData = cipher.doFinal(content);
            assert encryptData.length == content.length + 16;
            byte[] message = new byte[12 + content.length + 16];
            System.arraycopy(iv, 0, message, 0, 12);
            System.arraycopy(encryptData, 0, message, 12, encryptData.length);
            return message;
        } catch (Exception e) {
            log.error("AESGCM256加密文本处理失败,error:", e);
            throw new RuntimeException(e);
        }
    }

}
